<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Element Table 行合并与列合并</title>
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Microsoft YaHei', sans-serif;
    }

    body {
      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
      color: #333;
      min-height: 100vh;
      padding: 20px;
    }

    .container {
      max-width: 1200px;
      margin: 0 auto;
      background: white;
      border-radius: 12px;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
      overflow: hidden;
    }

    header {
      background: linear-gradient(90deg, #409EFF 0%, #337ecc 100%);
      color: white;
      padding: 25px 40px;
      text-align: center;
    }

    h1 {
      font-size: 2.4rem;
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 15px;
    }

    .subtitle {
      font-size: 1.1rem;
      opacity: 0.9;
      max-width: 800px;
      margin: 0 auto;
      line-height: 1.6;
    }

    .content-wrapper {
      display: flex;
      flex-direction: column;
      padding: 30px;
    }

    .card {
      background: white;
      border-radius: 10px;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
      margin-bottom: 30px;
      overflow: hidden;
    }

    .card-header {
      background: #f8fafc;
      padding: 18px 25px;
      border-bottom: 1px solid #eaeefb;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .card-title {
      font-size: 1.3rem;
      color: #409EFF;
      font-weight: 600;
    }

    .card-desc {
      color: #606266;
      font-size: 0.95rem;
      margin-top: 5px;
    }

    .card-body {
      padding: 25px;
    }

    .control-panel {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 20px;
      padding: 20px;
      background: #f8fafc;
      border-radius: 8px;
      margin-bottom: 30px;
    }

    .control-group {
      display: flex;
      flex-direction: column;
    }

    .control-label {
      margin-bottom: 10px;
      font-weight: 500;
      color: #606266;
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .control-label i {
      color: #409EFF;
    }

    .custom-table {
      border: 1px solid #ebeef5;
      border-radius: 6px;
      overflow: hidden;
    }

    .custom-table .el-table__header th {
      background-color: #f5f7fa;
      color: #606266;
      font-weight: 600;
    }

    .merged-cell {
      background-color: #ecf5ff !important;
      color: #409EFF !important;
      font-weight: 600;
      font-size: 16px;
      text-align: center;
    }

    .title-cell {
      background-color: #409EFF !important;
      color: white !important;
      font-size: 18px;
      font-weight: bold;
      text-align: center;
    }

    .dynamic-merged {
      background-color: #f0f9eb !important;
      color: #67c23a !important;
    }

    .code-block {
      background: #2d2d2d;
      color: #f8f8f2;
      border-radius: 6px;
      padding: 20px;
      margin-top: 20px;
      overflow-x: auto;
      font-family: 'Fira Code', monospace;
      font-size: 14px;
      line-height: 1.5;
    }

    .highlight {
      color: #f1fa8c;
    }

    .footer {
      text-align: center;
      padding: 25px;
      color: #909399;
      font-size: 0.9rem;
      border-top: 1px solid #ebeef5;
      background: #f8fafc;
    }

    @media (max-width: 768px) {
      .content-wrapper {
        padding: 15px;
      }

      h1 {
        font-size: 1.8rem;
      }

      .control-panel {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="container">
      <header>
        <h1><i class="el-icon-s-grid"></i> Element Table 行合并与列合并</h1>
        <p class="subtitle">使用 el-table 的 span-method 方法实现复杂的单元格合并，包括4行3列合并、动态合并等功能</p>
      </header>

      <div class="content-wrapper">
        <div class="control-panel">
          <div class="control-group">
            <label class="control-label">
              <i class="el-icon-setting"></i> 合并方案选择
            </label>
            <el-radio-group v-model="mergeType" @change="resetTableData">
              <el-radio-button label="fixed">固定位置合并</el-radio-button>
              <el-radio-button label="dynamic">动态数据合并</el-radio-button>
              <el-radio-button label="title">标题行合并</el-radio-button>
            </el-radio-group>
          </div>

          <div class="control-group" v-if="mergeType === 'fixed'">
            <label class="control-label">
              <i class="el-icon-position"></i> 合并起始位置
            </label>
            <el-select v-model="mergeStart" placeholder="请选择">
              <el-option v-for="item in positionOptions" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </div>

          <div class="control-group" v-if="mergeType === 'dynamic'">
            <label class="control-label">
              <i class="el-icon-connection"></i> 合并字段
            </label>
            <el-select v-model="mergeField" placeholder="请选择">
              <el-option v-for="field in fieldOptions" :key="field" :label="field" :value="field">
              </el-option>
            </el-select>
          </div>
        </div>

        <!-- 方案一：固定位置合并 -->
        <div class="card" v-if="mergeType === 'fixed'">
          <div class="card-header">
            <div>
              <div class="card-title">方案一：固定位置合并 (4行3列)</div>
              <div class="card-desc">合并指定位置的4行3列单元格，可调整起始位置</div>
            </div>
            <el-tag type="primary">当前起始位置: {{ mergeStartLabel }}</el-tag>
          </div>
          <div class="card-body">
            <el-table :data="tableData" border class="custom-table" :span-method="fixedSpanMethod" style="width: 100%">
              <el-table-column prop="id" label="ID" width="80" align="center"></el-table-column>
              <el-table-column prop="name" label="姓名" width="120"></el-table-column>
              <el-table-column prop="age" label="年龄" width="80" align="center"></el-table-column>
              <el-table-column prop="department" label="部门"></el-table-column>
              <el-table-column prop="position" label="职位"></el-table-column>
              <el-table-column prop="salary" label="薪资" align="right"></el-table-column>
              <el-table-column prop="joinDate" label="入职日期"></el-table-column>
            </el-table>

            <div class="code-block">
              <span class="highlight">// 固定位置合并方法</span><br>
              fixedSpanMethod({ row, column, rowIndex, columnIndex }) {<br>
              &nbsp;&nbsp;const [startRow, startCol] = this.mergeStart.split('-').map(Number);<br>
              &nbsp;&nbsp;const rowSpan = 4, colSpan = 3;<br><br>
              &nbsp;&nbsp;<span class="highlight">// 判断是否在合并区域内</span><br>
              &nbsp;&nbsp;if (rowIndex >= startRow && rowIndex < startRow + rowSpan &&<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;columnIndex >= startCol && columnIndex < startCol + colSpan) {<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;if (rowIndex === startRow && columnIndex === startCol) {<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 返回合并配置</span><br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rowspan: rowSpan,<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;colspan: colSpan,<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;} else {<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 其他单元格不显示</span><br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rowspan: 0,<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;colspan: 0,<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                  &nbsp;&nbsp;}<br>
                  }
            </div>
          </div>
        </div>

        <!-- 方案二：动态数据合并 -->
        <div class="card" v-if="mergeType === 'dynamic'">
          <div class="card-header">
            <div>
              <div class="card-title">方案二：动态数据合并</div>
              <div class="card-desc">根据数据字段自动合并相同值的连续行（4行3列合并）</div>
            </div>
            <el-tag type="success">合并字段: {{ mergeField }}</el-tag>
          </div>
          <div class="card-body">
            <el-table :data="dynamicData" border class="custom-table" :span-method="dynamicSpanMethod"
              style="width: 100%">
              <el-table-column prop="id" label="ID" width="80" align="center"></el-table-column>
              <el-table-column prop="name" label="产品名称"></el-table-column>
              <el-table-column prop="category" :label="'类别 (' + mergeField + ')'"></el-table-column>
              <el-table-column prop="price" label="价格" align="right"></el-table-column>
              <el-table-column prop="stock" label="库存" align="center"></el-table-column>
              <el-table-column prop="sales" label="销量" align="center"></el-table-column>
              <el-table-column prop="status" label="状态"></el-table-column>
            </el-table>

            <div class="code-block">
              <span class="highlight">// 动态合并方法</span><br>
              dynamicSpanMethod({ row, column, rowIndex, columnIndex }) {<br>
              &nbsp;&nbsp;const fields = ['category', 'status'];<br>
              &nbsp;&nbsp;if (fields.includes(this.mergeField)) {<br>
              &nbsp;&nbsp;&nbsp;&nbsp;if (columnIndex === 2 || columnIndex === 3 || columnIndex === 4) {<br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 计算合并行数</span><br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const prevRow = rowIndex > 0 ? this.dynamicData[rowIndex - 1] :
              null;<br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const nextRow1 = rowIndex + 1 < this.dynamicData.length ?
                this.dynamicData[rowIndex + 1] : null;<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const nextRow2 = rowIndex + 2 < this.dynamicData.length ?
                  this.dynamicData[rowIndex + 2] : null;<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const nextRow3 = rowIndex + 3 < this.dynamicData.length ?
                    this.dynamicData[rowIndex + 3] : null;<br><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 判断是否连续4行相同</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (prevRow && prevRow[this.mergeField] ===
                    row[this.mergeField]) {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 0, colspan: 0 };<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nextRow1 && nextRow1[this.mergeField] ===
                    row[this.mergeField] &&<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nextRow2 && nextRow2[this.mergeField] ===
                    row[this.mergeField] &&<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nextRow3 && nextRow3[this.mergeField] ===
                    row[this.mergeField]<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 4, colspan: 1 };<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                    &nbsp;&nbsp;}<br>
                    &nbsp;&nbsp;return { rowspan: 1, colspan: 1 };<br>
                    }
            </div>
          </div>
        </div>

        <!-- 方案三：标题行合并 -->
        <div class="card" v-if="mergeType === 'title'">
          <div class="card-header">
            <div>
              <div class="card-title">方案三：标题行合并</div>
              <div class="card-desc">跨多行多列的表头合并，常用于标题行</div>
            </div>
            <el-tag type="warning">跨3列合并</el-tag>
          </div>
          <div class="card-body">
            <el-table :data="titleData" border class="custom-table" :span-method="titleSpanMethod" style="width: 100%">
              <el-table-column prop="year" label="年份" width="120" align="center"></el-table-column>
              <el-table-column prop="quarter" label="季度" width="100" align="center"></el-table-column>
              <el-table-column prop="product" label="产品" width="150"></el-table-column>
              <el-table-column prop="q1" label="Q1销售额" align="right"></el-table-column>
              <el-table-column prop="q2" label="Q2销售额" align="right"></el-table-column>
              <el-table-column prop="q3" label="Q3销售额" align="right"></el-table-column>
              <el-table-column prop="q4" label="Q4销售额" align="right"></el-table-column>
              <el-table-column prop="total" label="年度总计" align="right"></el-table-column>
            </el-table>

            <div class="code-block">
              <span class="highlight">// 标题行合并方法</span><br>
              titleSpanMethod({ row, column, rowIndex, columnIndex }) {<br>
              &nbsp;&nbsp;<span class="highlight">// 第一行合并</span><br>
              &nbsp;&nbsp;if (rowIndex === 0) {<br>
              &nbsp;&nbsp;&nbsp;&nbsp;if (columnIndex === 0) {<br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 年份列合并两行</span><br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 2, colspan: 1 };<br>
              &nbsp;&nbsp;&nbsp;&nbsp;} else if (columnIndex === 1) {<br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 季度列合并两行</span><br>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 2, colspan: 1 };<br>
              &nbsp;&nbsp;&nbsp;&nbsp;} else if (columnIndex >= 3 && columnIndex <= 6) {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 销售额标题合并4列</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (columnIndex === 3) {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 1, colspan: 4 };<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 0, colspan: 0 };<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
                &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                &nbsp;&nbsp;}<br>
                &nbsp;&nbsp;<span class="highlight">// 第二行处理</span><br>
                &nbsp;&nbsp;if (rowIndex === 1 && columnIndex >= 3 && columnIndex <= 6) {<br>
                  &nbsp;&nbsp;&nbsp;&nbsp;<span class="highlight">// 季度销售额列正常显示</span><br>
                  &nbsp;&nbsp;&nbsp;&nbsp;return { rowspan: 1, colspan: 1 };<br>
                  &nbsp;&nbsp;}<br>
                  }
            </div>
          </div>
        </div>
      </div>

      <div class="footer">
        <p>Element UI 表格合并单元格示例 | 4行3列合并实现 | © 2023</p>
      </div>
    </div>
  </div>

  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          mergeType: 'fixed', // fixed, dynamic, title
          mergeStart: '1-1', // 起始位置 (行-列)
          mergeField: 'category', // 动态合并字段
          positionOptions: [
            { value: '0-0', label: '位置: 第1行第1列' },
            { value: '1-1', label: '位置: 第2行第2列' },
            { value: '2-3', label: '位置: 第3行第4列' },
            { value: '3-2', label: '位置: 第4行第3列' },
            { value: '4-4', label: '位置: 第5行第5列' }
          ],
          fieldOptions: ['category', 'status'],
          tableData: [
            { id: 1, name: '张三', age: 28, department: '技术部', position: '前端工程师', salary: '18,000', joinDate: '2020-03-15' },
            { id: 2, name: '李四', age: 32, department: '技术部', position: '后端工程师', salary: '20,000', joinDate: '2019-07-22' },
            { id: 3, name: '王五', age: 25, department: '设计部', position: 'UI设计师', salary: '15,000', joinDate: '2021-01-10' },
            { id: 4, name: '赵六', age: 29, department: '产品部', position: '产品经理', salary: '22,000', joinDate: '2018-11-05' },
            { id: 5, name: '钱七', age: 35, department: '市场部', position: '市场总监', salary: '25,000', joinDate: '2017-05-30' },
            { id: 6, name: '孙八', age: 27, department: '技术部', position: '测试工程师', salary: '14,000', joinDate: '2020-09-12' },
            { id: 7, name: '周九', age: 31, department: '销售部', position: '销售主管', salary: '16,000', joinDate: '2019-03-18' }
          ],
          dynamicData: [
            { id: 1001, name: '笔记本电脑', category: '电子产品', price: '¥6,299', stock: 45, sales: 120, status: '热销' },
            { id: 1002, name: '智能手机', category: '电子产品', price: '¥3,999', stock: 32, sales: 210, status: '热销' },
            { id: 1003, name: '平板电脑', category: '电子产品', price: '¥2,599', stock: 28, sales: 95, status: '热销' },
            { id: 1004, name: '无线耳机', category: '电子产品', price: '¥899', stock: 56, sales: 180, status: '热销' },
            { id: 2001, name: '办公椅', category: '家具', price: '¥1,299', stock: 15, sales: 32, status: '正常' },
            { id: 2002, name: '书桌', category: '家具', price: '¥2,199', stock: 8, sales: 18, status: '正常' },
            { id: 3001, name: '运动鞋', category: '服装', price: '¥599', stock: 67, sales: 85, status: '促销' },
            { id: 3002, name: 'T恤', category: '服装', price: '¥199', stock: 120, sales: 210, status: '促销' }
          ],
          titleData: [
            { year: '2023', quarter: 'Q1', product: '产品A', q1: '125,000', q2: '', q3: '', q4: '', total: '' },
            { year: '', quarter: 'Q2', product: '产品A', q1: '', q2: '138,000', q3: '', q4: '', total: '' },
            { year: '', quarter: 'Q3', product: '产品A', q1: '', q2: '', q3: '156,000', q4: '', total: '' },
            { year: '', quarter: 'Q4', product: '产品A', q1: '', q2: '', q3: '', q4: '168,000', total: '587,000' },
            { year: '2023', quarter: 'Q1', product: '产品B', q1: '89,000', q2: '', q3: '', q4: '', total: '' },
            { year: '', quarter: 'Q2', product: '产品B', q1: '', q2: '95,000', q3: '', q4: '', total: '' },
            { year: '', quarter: 'Q3', product: '产品B', q1: '', q2: '', q3: '102,000', q4: '', total: '' },
            { year: '', quarter: 'Q4', product: '产品B', q1: '', q2: '', q3: '', q4: '115,000', total: '401,000' }
          ]
        };
      },
      computed: {
        mergeStartLabel() {
          const option = this.positionOptions.find(opt => opt.value === this.mergeStart);
          return option ? option.label : '';
        }
      },
      methods: {
        // 重置表格数据
        resetTableData() {
          // 这里可以根据需要重置数据
        },

        // 方案一：固定位置合并方法 (4行3列)
        fixedSpanMethod({ row, column, rowIndex, columnIndex }) {
          const [startRow, startCol] = this.mergeStart.split('-').map(Number);
          const rowSpan = 4;
          const colSpan = 3;

          // 判断是否在合并区域内
          if (rowIndex >= startRow && rowIndex < startRow + rowSpan &&
            columnIndex >= startCol && columnIndex < startCol + colSpan) {

            // 左上角单元格返回合并配置
            if (rowIndex === startRow && columnIndex === startCol) {
              return {
                rowspan: rowSpan,
                colspan: colSpan,
              };
            } else {
              // 其他单元格不显示
              return {
                rowspan: 0,
                colspan: 0,
              };
            }
          }

          // 不在合并区域，正常显示
          return {
            rowspan: 1,
            colspan: 1,
          };
        },

        // 方案二：动态数据合并方法 (4行3列)
        dynamicSpanMethod({ row, column, rowIndex, columnIndex }) {
          // 只对类别和状态列进行合并
          const fields = ['category', 'status'];

          if (fields.includes(this.mergeField)) {
            // 合并第3、4、5列（类别/状态、价格、库存）
            if (columnIndex === 2 || columnIndex === 3 || columnIndex === 4) {
              // 获取当前行和前几行的数据
              const prevRow = rowIndex > 0 ? this.dynamicData[rowIndex - 1] : null;
              const nextRow1 = rowIndex + 1 < this.dynamicData.length ? this.dynamicData[rowIndex + 1] : null;
              const nextRow2 = rowIndex + 2 < this.dynamicData.length ? this.dynamicData[rowIndex + 2] : null;
              const nextRow3 = rowIndex + 3 < this.dynamicData.length ? this.dynamicData[rowIndex + 3] : null;

              // 如果上一行与当前行相同，则隐藏当前单元格
              if (prevRow && prevRow[this.mergeField] === row[this.mergeField]) {
                return {
                  rowspan: 0,
                  colspan: 0,
                };
              }
              // 如果连续4行相同，则合并
              else if (
                nextRow1 && nextRow1[this.mergeField] === row[this.mergeField] &&
                nextRow2 && nextRow2[this.mergeField] === row[this.mergeField] &&
                nextRow3 && nextRow3[this.mergeField] === row[this.mergeField]
              ) {
                return {
                  rowspan: 4,
                  colspan: 1,
                };
              }
            }
          }

          // 默认情况，显示一个单元格
          return {
            rowspan: 1,
            colspan: 1,
          };
        },

        // 方案三：标题行合并方法
        titleSpanMethod({ row, column, rowIndex, columnIndex }) {
          // 第一行（标题行）
          if (rowIndex === 0) {
            // 年份列合并两行
            if (columnIndex === 0) {
              return {
                rowspan: 4,
                colspan: 1
              };
            }
            // 季度列合并两行
            else if (columnIndex === 1) {
              return {
                rowspan: 4,
                colspan: 1
              };
            }
            // 销售额标题合并4列
            else if (columnIndex >= 3 && columnIndex <= 6) {
              if (columnIndex === 3) {
                return {
                  rowspan: 1,
                  colspan: 4
                };
              } else {
                return {
                  rowspan: 0,
                  colspan: 0
                };
              }
            }
          }

          // 其他行正常显示
          return {
            rowspan: 1,
            colspan: 1
          };
        }
      }
    });
  </script>
</body>

</html>